package com.js.service.bot.basics;

import com.github.pagehelper.PageHelper;
import com.js.common.annotation.ResponseClass;
import com.js.common.constant.Const;
import com.js.domian.entity.bot.CommandEntity;
import com.js.domian.entity.bot.ResponseEntity;
import com.js.domian.vo.bot.ResponseVo;
import com.js.mapper.bot.ResponseMapper;
import com.js.service.bot.response.BaseService;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class ResponseService {

    private final ResponseMapper responseMapper;
    private final ApplicationContext applicationContext;

    public List<ResponseEntity> getResponseList(ResponseVo vo){
        PageHelper.startPage(vo);
        List<ResponseEntity> list = responseMapper.getResponseList(vo);
        list.forEach(response -> {
            BaseService service = (BaseService) applicationContext.getBean(response.getResponseClass());
            ResponseClass responseClass = service.getClass().getAnnotation(ResponseClass.class);
            response.setResponseClassName(responseClass.value());
            response.setCommandList(responseMapper.getCommandByResponseId(response.getId()));
        });
        return list;
    }

    public ResponseEntity getResponse(Integer id){
        return responseMapper.getResponse(id);
    }

    @Cacheable(value="botCache",key="'getResponseList_'+#websocketId")
    public List<ResponseEntity> getResponseListByWebsocketId(Integer websocketId){
        ResponseVo vo = new ResponseVo();
        vo.setWebsocketId(websocketId);
        vo.setEnable(Const.BASE_YES_NO.YES.getValue());
        return getResponseList(vo);
    }

    @CacheEvict(value="botCache",key="'getResponseList_'+#entity.getWebsocketId()")
    @Transactional(rollbackFor = Exception.class)
    public void addResponse(ResponseEntity entity){
        Integer id = entity.getId();
        if(id == null){
            responseMapper.addResponse(entity);
            id = entity.getId();
        }else{
            responseMapper.updateResponse(entity);
            responseMapper.deleteCommand(id);
        }
        for (CommandEntity command : entity.getCommandList()) {
            command.setResponseId(id);
            responseMapper.addCommand(command);
        }
    }

    @CacheEvict(value="botCache",key="'getResponseList_'+#result")
    @Transactional(rollbackFor = Exception.class)
    public Integer deleteResponse(Integer id){
        ResponseEntity entity = getResponse(id);
        responseMapper.deleteResponse(id);
        responseMapper.deleteCommand(id);
        return entity.getWebsocketId();
    }

    @CacheEvict(value="botCache",key="'getResponseList_'+#websocketId")
    @Transactional(rollbackFor = Exception.class)
    public void deleteResponseByWebsocketId(Integer websocketId){
        responseMapper.deleteResponseByWebsocketId(websocketId);
    }

    public List<Map<String, String>> getAllResponseClass(){
        List<Map<String, String>> list = new ArrayList<>();
        Map<String, BaseService> serviceMap =  applicationContext.getBeansOfType(BaseService.class);
        for (String key : serviceMap.keySet()) {
            Map<String, String> map = new HashMap<>();
            BaseService service = serviceMap.get(key);
            ResponseClass responseClass = service.getClass().getAnnotation(ResponseClass.class);
            map.put("key", key);
            map.put("name", responseClass.value());
            list.add(map);
        }
        return list;
    }
}
